home *** CD-ROM | disk | FTP | other *** search
-
- /*/*************************************************************************
- ** PowerBook Software Group
- **
- ** PowerBook's Zoomed Video Driver Sample
- **
- ** by Philip Nguyen , (nguyen.p@apple.com)
- ** PowerBook Software Group
- **
- ** with help from Dave Falkenberg
- **
- ** " It works on my PowerBook! "
- **
- ** File: ZVDrvr.c
- **
- ** Copyright © 1996 Apple Computer, Inc.
- ** All rights reserved.
- **
- ** You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "DSC Sample Code"
- ** after having made changes. If you're going to re-distribute the source,
- ** we require that you make it clear in the source that the code was
- ** descended from Apple Sample Code, but that you've made changes.
- **
- **************************************************************************/
-
- #define BUILDING_FOR_SYSTEM7 1
-
- #include <Devices.h>
- #include <DriverServices.h>
- #include <NameRegistry.h>
- #include <QuickTimeComponents.h>
- #include <Types.h>
-
- #include "AcmeZVDrvr.h"
- #include "ZoomedVideo.h"
-
-
- //=====================================================================================================
- //
- // Forward declarations.
- //
- //=====================================================================================================
- OSStatus DoDriverIO(AddressSpaceID addressSpaceID, IOCommandID ioCommandID, IOCommandContents ioCommandContents, IOCommandCode ioCommandCode, IOCommandKind ioCommandKind);
- static OSStatus DoInitialization(SInt16 refNum, const RegEntryIDPtr regEntryID, Boolean replacingDriver);
- static OSStatus DoFinalization(SInt16 refNum, const RegEntryIDPtr regEntryID, Boolean beingReplaced);
- static OSStatus DoHardwareInit(Boolean open);
- static OSStatus DoControl(CntrlParam *pb);
- static OSStatus DoStatus(CntrlParam *pb);
- static OSStatus GetZoomVideo(ZVFlagRecord *zvStatus);
- static OSStatus DoZoomVideo(ZVFlagRecord *turnZVOn);
- static OSStatus CheckInputCapabilities(UInt32 *inputFlag);
- static OSStatus GetZVInfo(ZVInfo *myData);
- static OSStatus DoAnalogControl(ZVAnalogControlRecord *analogData);
- static OSStatus DoCheckVsync(ZVFlagRecord * vSync);
- static OSStatus DoSetInputSource( UInt16 * inputSource);
- static OSStatus DoSetInputStandard( UInt16 * inputStandard);
- static UInt16 CheckVsyn(void);
- static OSStatus DoGetAnalogDefaults( ZVAnalogControlRecord * myData);
- static OSStatus DoGetNumberOfInputs( UInt16 *numberOfInputs );
- static OSStatus DoGetInput( UInt16 *inputSource );
- static OSStatus DoGetInputFormat( UInt16 *inputSource );
- static OSStatus WriteSIOLoop(UInt16 data);
- static void WriteSIO(UInt16 byte);
- static void SIOSendByte(UInt8 SIOdata);
- static void SIORegWrite(UInt8 data);
- static void SIOStart(Boolean start);
- static UInt8 AdjustSIOData(UInt8 data);
-
-
- //=====================================================================================================
- //
- // Globals
- //
- //=====================================================================================================
- volatile ZVRegisters *gZVRegisters;
- RegEntryID gRegEntryID;
- UInt8 gvalue;
- Boolean gZVideoOn;
- UInt16 gSaturation;
- UInt16 gBrightness;
-
-
- //=====================================================================================================
- //
- // The DriverDescription
- //
- //=====================================================================================================
- #pragma mark TheDriverDescription
- enum
- {
- kMajorRev = 1,
- kMinorAndBugRev = 1,
- kStage = alphaStage, // developStage, alphaStage, betaStage, finalStage
- kNonRelRev = 1
- };
-
- DriverDescription TheDriverDescription = {
- kTheDescriptionSignature, // Driver Desrciption Signature
- kInitialDriverDescriptor, // Driver Description Version
-
- // driverType
- {
- kZVNodeName, // DeviceName (matches name registry node name)
- kMajorRev, kMinorAndBugRev, kStage, kNonRelRev, // Driver version
- },
-
- // driverOSRuntimeInfo
- {
- kDriverIsLoadedUponDiscovery | kDriverIsOpenedUponLoad, // Runtime Options
- kZVDriverName, // Unit Table Driver Name
- },
-
- // driverSerives
- 1, // nServices
- kServiceCategoryNdrvDriver, // Service Category ('ndrv')
- kNdrvTypeIsGeneric, // Type withing category (generic)
- 1, 0, finalStage, 0 // Version of the DriverDescription format
- };
-
-
- //=====================================================================================================
- //
- // The DriverDescription
- //
- //=====================================================================================================
- #pragma mark -
- #pragma mark ••••• Standard Native Driver Functions •••••
-
- OSStatus DoDriverIO( AddressSpaceID addressSpaceID,
- IOCommandID ioCommandID,
- IOCommandContents ioCommandContents,
- IOCommandCode ioCommandCode,
- IOCommandKind ioCommandKind)
- {
- #pragma unused (addressSpaceID)
-
- OSStatus status = noErr;
-
- /*
- * Note: Initialize, Open, KillIO, Close, and Finalize are either synchronous
- * or immediate. Read, Write, Control, and Status may be immediate,
- * synchronous, or asynchronous.
- */
- switch (ioCommandCode)
- {
- case kInitializeCommand: /* Initialize */
- case kReplaceCommand: /* or replace an old driver */
-
- status = DoInitialization( ioCommandContents.initialInfo->refNum,
- &ioCommandContents.initialInfo->deviceEntry,
- (ioCommandCode == kReplaceCommand));
- break;
-
- case kFinalizeCommand: /* Finalize */
- case kSupersededCommand: /* or get ready to be replaced */
-
- status = DoFinalization( ioCommandContents.initialInfo->refNum,
- &ioCommandContents.initialInfo->deviceEntry,
- (ioCommandCode == kSupersededCommand));
- break;
-
- case kOpenCommand: /* Open and Close don’t do anything */
- status = DoHardwareInit(true);
- break;
-
- case kCloseCommand:
- status = DoHardwareInit(false);
- break;
-
- case kControlCommand:
- status = DoControl((CntrlParam *) ioCommandContents.pb);
- break;
-
- case kStatusCommand:
- status = DoStatus((CntrlParam *) ioCommandContents.pb);
- break;
-
- case kReadCommand:
- case kWriteCommand:
- case kKillIOCommand:
- default:
- status = paramErr;
- break;
- }
-
- /*
- * Force a valid result for immediate commands -- they must return a valid
- * status to the Driver Manager: returning kIOBusyStatus would be a bug..
- * Non-immediate commands return a status from the lower-level routine. If the
- * status is kIOBusyStatus, we just return -- an asynchronous I/O completion
- * routine will eventually complete the request. If it's some other status, the
- * lower-level routine has completed a non-immediate task, so we call
- * IOCommandIsComplete and return its (presumably noErr) status.
- */
- if ((ioCommandKind & kImmediateIOCommandKind) != 0)
- {
- /* Immediate commands return the operation status */
- }
- else if (status == ioInProgress)
- {
- /*
- * An asynchronous operation is in progress. The driver handler promises
- * to call IOCommandIsComplete when the operation concludes.
- */
- status = noErr;
- }
- else
- {
- /*
- * Normal command that completed synchronously. Dequeue the user's
- * parameter block.
- */
- status = IOCommandIsComplete(ioCommandID, status);
- }
-
- return status;
- }
-
-
- //=====================================================================================================
- //
- // DoInitialization
- //
- // -> regEntryID The NameRegistry ID for this device.
- //
- // -> replacingDriver
- // This indicates whether the driver is being initialized (replacingDriver == false) or replaced
- // (replacingDriver == true).
- // These commands are similar, but with subtle differences. A 'initialize' command is issued
- // if no version of this driver has been previously loaded, whereas a 'replace' is
- // issued if a previous version of the driver has been loaded, but subsequently superseded.
- //
- // This routine should initialize the hardware to a known state and initialize any globals. If the
- // regEntryID is needed later on, then one should make a copy and store it in the globals.
- //=====================================================================================================
- static OSStatus DoInitialization(SInt16 refNum, const RegEntryIDPtr regEntryID, Boolean replacingDriver)
- {
- #pragma unused (refNum,replacingDriver)
-
- OSStatus status;
- RegPropertyValueSize propertySize;
-
- // Save the regEntryID,
- RegistryEntryIDCopy(regEntryID, &gRegEntryID);
-
- // Look for our AAPL,address property, so we can get the base address of our card.
- // First, see if it exists by attempting to get its size
- status = RegistryPropertyGetSize(regEntryID,"AAPL,address",&propertySize);
- if (status == noErr)
- {
- status = RegistryPropertyGet( regEntryID, "AAPL,address", (RegPropertyValue *) &gZVRegisters,&propertySize);
- }
-
- return status;
- }
-
-
- //=====================================================================================================
- //
- // DoFinalization
- //
- // This routine is called after getting a 'kFinalizeCommand' or 'kSupersededCommandin DoDriverIO().
- // A 'kFinalizeCommand' is issued if the driver is going away for good, and a 'kSupersededCommand' is
- // issued if the driver will be replaced with a later, greater version.
- //
- // This routine should dispose of any data that was allocated in the initialize command.
- //=====================================================================================================
- static OSStatus DoFinalization(SInt16 refNum, const RegEntryIDPtr regEntryID, Boolean beingReplaced)
- {
- #pragma unused (refNum,regEntryID,beingReplaced)
-
- // Dispose of the regEntryID we created earlier.
- RegistryEntryIDDispose(&gRegEntryID);
-
- return noErr;
- }
-
-
- #pragma mark -
- #pragma mark ••••• Driver Specific Calls •••••
- //=====================================================================================================
- //
- // DoHardwareInit
- //
- // Perform any necessary hardware initialization required, or if open == false, any termination
- // required.
- //
- //=====================================================================================================
- static OSStatus DoHardwareInit(Boolean open)
- {
- #pragma unused (open)
-
- return noErr;
- }
-
-
- //=====================================================================================================
- //
- // DoControl
- //
- // Process a PBControl command. This is the main entry point for ZV calls.
- //
- //=====================================================================================================
- static OSStatus DoControl(CntrlParam *pb)
- {
- OSErr status = controlErr;
- void * genericPtr;
-
- // The 'csParam' field of the 'CntrlParam' stucture is defined as 'short csParam[11]'. This is
- // meant for 'operation defined parameters.' For the AV driver, only the first 4 bytes are
- // used. They are used as a pointer to another structure.
- // To help code readability, the pointer will be extracted as a generic 'void *' and then cast as
- // appropriate.
-
- genericPtr = (void *) *((UInt32 *) &(pb->csParam[0]));
-
- switch (pb->csCode)
- {
- case cscZVVideoEnable:
- status = DoZoomVideo( (ZVFlagRecord *) genericPtr );
- break;
-
- case cscZVSetCurrentAnalogValue: // Analog controls
- status = DoAnalogControl( (ZVAnalogControlRecord *) genericPtr );
- break;
-
- case cscZVSetInput:
- status = DoSetInputSource( (UInt16 *) genericPtr );
- break;
-
- case cscZVSetInputStandard:
- status = DoSetInputStandard( (UInt16 *) genericPtr );
- break;
-
- default: /* Unknown csCode */
- status = controlErr;
- break;
- }
-
- return status;
- }
-
- //=====================================================================================================
- //
- // DoStatus
- //
- // Process a PBStatus command. This is the main entry point for ZV calls.
- //
- //=====================================================================================================
- static OSStatus DoStatus(CntrlParam *pb)
- {
- OSErr status = statusErr;
- void * genericPtr;
-
- // The 'csParam' field of the 'CntrlParam' stucture is defined as 'short csParam[11]'. This is
- // meant for 'operation defined parameters.' For the AV driver, only the first 4 bytes are
- // used. They are used as a pointer to another structure.
- // To help code readability, the pointer will be extracted as a generic 'void *' and then cast as
- // appropriate.
-
- genericPtr = (void *) *((UInt32 *) &(pb->csParam[0]));
-
- switch (pb->csCode)
- {
- case cscZVGetVideoEnable:
- status = GetZoomVideo( (ZVFlagRecord *) genericPtr );
- break;
-
- case cscZVGetDefaultAnalogValue:
- status = DoGetAnalogDefaults( (ZVAnalogControlRecord *) genericPtr );
- break;
-
- case cscZVGetVSyncState: // check for Vsync
- status = DoCheckVsync( (ZVFlagRecord *) genericPtr );
- break;
-
- case cscZVGetInputFlags: // check for input capabilities
- status = CheckInputCapabilities( (UInt32 *) genericPtr );
- break;
-
- case cscZVGetInfo: // get input HW capability
- status = GetZVInfo( (ZVInfo *) genericPtr );
- break;
-
- case cscZVGetNumberOfInputs:
- status = DoGetNumberOfInputs( (UInt16 *) genericPtr );
- break;
-
- case cscZVGetInput:
- status = DoGetInput( (UInt16 *) genericPtr );
- break;
-
- case cscZVGetInputFormat:
- status = DoGetInputFormat( (UInt16 *) genericPtr );
- break;
-
- default: /* Unknown csCode */
- status = statusErr;
- break;
- }
-
- return status;
- }
-
-
- //=====================================================================================================
- //
- // GetZoomVideo
- //
- //=====================================================================================================
- static OSStatus GetZoomVideo( ZVFlagRecord *zvStatus)
- {
- zvStatus->csFlag = gZVideoOn;
-
- return noErr;
- }
-
- //=====================================================================================================
- //
- // DoZoomVideo
- //
- //=====================================================================================================
- static OSStatus DoZoomVideo( ZVFlagRecord *turnZVOn)
- {
- OSStatus status = noErr;
-
- // do I/O write to port 01 to turn on ZV port
- // bit 0 is video control
- // bit 1 is audio control
- // (0x3 turns them both on)
-
- if (turnZVOn->csFlag)
- {
- // Do whatever is needed to enable ZoomVideo and set the status flag
- gZVideoOn = true;
- status = noErr;
- }
- else
- {
- // Do whatever is needed to disable ZoomVideo and set the status flag
- gZVideoOn = false;
- status = noErr;
- }
-
- return status;
- }
-
- //=====================================================================================================
- //
- // CheckInputCapabilities
- //
- // This routine is used by the on-board video digitizer to determine the capabilities of the ZV card.
- // It mirrors the input capability flags described in Inside Macintosh: QuickTime Components, Chapter 8: Video
- // Digitizer Components, pages 8-14 through 8-15.
- //
- //=====================================================================================================
- static OSStatus CheckInputCapabilities(UInt32 * inputFlag)
- {
- *inputFlag = (digiInDoesNTSC | digiInDoesComposite | digiInDoesColor) ;
- return noErr;
- }
-
-
- //=====================================================================================================
- //
- // GetZVInfo
- //
- // Returns information about the ZV card. The different parameters are:
- //
- // features: Describes the different capabilities of the ZV Card
- // isInterlaced: Indicates whether the ZV data contains multiple fields. 0 = no, 1 = yes
- // inputFormat: Indicates what format the ZV data is in (composite, s-video, component)
- // activeRect: Indicates the coordinates for the video rectangle.
- //
- //=====================================================================================================
- static OSStatus GetZVInfo(ZVInfo * zvInfo)
- {
- OSStatus status = noErr;
-
- // Set up the features that our card supports
- zvInfo->features = kZVHasBrightness | kZVHasSaturation;
-
- // Report the current input flags. Note that since we only have one input and only
- // support one standard, the currentFlags is not different from the ones reported in the
- // CheckInputCapabilities. If we were to support more than one standard, for example, then
- // we would only report the current standard.
- zvInfo->currentFlags = (digiInDoesNTSC | digiInDoesComposite | digiInDoesColor);
-
- // This is active/crop rectangle for our ZV card
- zvInfo->activeRect.top = 0x001A;
- zvInfo->activeRect.left = 0x0008;
- zvInfo->activeRect.bottom = 0x01FA;
- zvInfo->activeRect.right = 0x0288;
-
- // Our card always does interlace, so report it here
- zvInfo->isInterlaced = true;
-
- return status;
- }
-
-
- //=====================================================================================================
- //
- // DoGetNumberOfInputs
- //
- // Returns the number of inputs supported by the ZV Card
- //
- //=====================================================================================================
- static OSStatus DoGetNumberOfInputs( UInt16 *numberOfInputs )
- {
- // We only support one input, so return that value here. If we supported more than one, we would
- // report that here:
- *numberOfInputs = 1;
-
- return noErr;
- }
-
-
- //=====================================================================================================
- //
- // DoGetInput
- //
- // Returns the active input (zero-based).
- //
- //=====================================================================================================
- static OSStatus DoGetInput( UInt16 *inputSource )
- {
- // We only support one input, so we always say that source 0 is active. If we supported more than one, we would
- // report that here:
- *inputSource = 0;
-
- return noErr;
- }
-
-
- //=====================================================================================================
- //
- // DoGetInputFormat
- //
- // Returns the format for the desired input source.
- //
- //=====================================================================================================
- static OSStatus DoGetInputFormat( UInt16 *inputSource )
- {
-
- // We only support one format
-
- *inputSource = compositeIn;
-
- return noErr;
- }
-
-
- //=====================================================================================================
- //
- // DoGetAnalogDefaults
- //
- // Returns the default values for the supported analog settings.
- //
- //=====================================================================================================
- static OSStatus DoGetAnalogDefaults( ZVAnalogControlRecord * myData)
- {
- OSStatus status = noErr;
- UInt16 defaultValue;
-
- // Look at the whichControl field and return the appropriate default
- // value. Note that we do not support kZVWhiteLevel or kZVBlackLevel, so
- // we return a qtParamErr
-
- switch (myData->whichControl )
- {
- case kZVBrightness:
- defaultValue = 0xa000;
- break;
-
- case kZVSaturation:
- defaultValue = 0x8500;
- break;
-
- case kZVHue:
- defaultValue = 0x8000;
- break;
-
- case kZVContrast:
- defaultValue = 0x8000;
- break;
-
- case kZVSharpness:
- defaultValue = 0x8000;
- break;
-
- default:
- status = qtParamErr;
- break;
- }
-
- // Return the default value
- if ( status == noErr )
- myData->value = defaultValue;
-
- return status;
- }
-
- //=====================================================================================================
- //
- // DoAnalogControl
- //
- // Do the analog adjustment controls for SIO
- //
- //=====================================================================================================
- static OSStatus DoAnalogControl( ZVAnalogControlRecord *analogData )
- {
- OSStatus status = noErr;
- UInt8 data;
- UInt8 result;
- UInt16 returnData;
-
- // The "value" parameter in the ZVAnalogControlRecord is a UInt16. The actual value
- // mirrors the corresponding parameter in the QuickTime VideoDigitizer section
- data = ((analogData->value)>>12);
- result = AdjustSIOData(data);
-
- switch (analogData->whichControl )
- {
- case kZVBrightness:
- returnData = 0x1100 | result;
- gBrightness = analogData->value;
- break;
- case kZVSaturation:
- returnData = 0x1500 | result;
- gSaturation = analogData->value;
- break;
- default:
- returnData = 0x0000 | result;
- break;
- }
-
- // Send I2C here
- WriteSIOLoop(returnData);
- return status;
- }
-
- //=====================================================================================================
- //
- // DoCheckVsync
- //
- // This routine will wait until a VSync signal is seen and will timeout after 18ms. The status of
- // VSync signal is returned in the vsyncFlag parameter.
- //
- //=====================================================================================================
- static OSStatus DoCheckVsync( ZVFlagRecord * vSync)
- {
- UInt8 timeOut = 18;
- UInt8 value;
- OSStatus error = noErr;
-
- //
- while (timeOut-- > 0)
- {
- DelayForHardware(DurationToAbsolute(durationMillisecond * 1)); // wait 1 ms
- value = gZVRegisters->zvInterrupt ;
- if ( value & 0x02 )
- {
- vSync->csFlag = true;
- break;
- }
- }
-
- vSync->csFlag = false;
-
- return error;
- }
-
- //=====================================================================================================
- //
- // DoSetInputSource
- //
- // This routine tells us to set the input source to be one of the zero-based inputs.
- //
- //=====================================================================================================
- static OSStatus DoSetInputSource( UInt16 * inputNumber)
- {
- OSStatus error = noErr;
-
- // We only support one input, so the inputNumber has to be zero.
- if ( *inputNumber != 0 )
- error = qtParamErr;
-
- // If we actually supported more than one source, then we would do a range check and then
- // hit the hardware to change to the specified source.
-
- return error;
- }
-
- //=====================================================================================================
- //
- // DoSetInputStandard
- //
- // This routine tells us to set the input standard of the selected source..
- //
- //=====================================================================================================
- static OSStatus DoSetInputStandard( UInt16 * inputStandard)
- {
- OSStatus error = noErr;
-
- // We only support NSTC, so if the parameter is not NTSC then report an error.
- if ( *inputStandard != ntscIn )
- error = qtParamErr;
-
- // If we actually supported more than one standard, then we would do a range check and then
- // hit the hardware to change to the specified standard.
-
- return error;
- }
-
-
- #pragma mark -
- #pragma mark ••••• Utility Routines •••••
-
- //=====================================================================================================
- //
- // WriteSIOLoop
- //
- // WriteSIO writes one byte of data into SIO register to adjust Brightness
- //
- //=====================================================================================================
- static OSStatus WriteSIOLoop(UInt16 data)
- {
- OSStatus status = noErr;
- UInt8 i,j;
-
- i = 0;
- j = 0;
- // Send the SIO command
- while (i<4) {
- if (CheckVsyn() == 1) {
- WriteSIO(data);
- i++;
- }
- }
- // Send the termination command
- while (j<2) {
- if (CheckVsyn() == 1) {
- WriteSIO(0x0000);
- j++;
- }
- }
- return status;
- }
-
-
- //=====================================================================================================
- //
- // WriteSIOLoop
- //
- //=====================================================================================================
- static void WriteSIO(UInt16 byte)
- {
- OSStatus status = noErr;
- UInt8 data,cmd;
-
- data = (byte & 0xFF) ;
- cmd = byte >> 8;
- SIOStart(true);
- SIOSendByte( cmd );
- SIOSendByte ( data );
- SIOSendByte ( 0x00 );
- SIOSendByte ( 0x00 );
- SIOSendByte ( 0x00 );
- SIOSendByte ( 0x00 );
- SIOSendByte ( 0x00 );
- SIOSendByte ( 0x00 );
- SIOStart(false);
- }
- //=====================================================================================================
- //
- // SIOSendByte
- //
- //=====================================================================================================
- static void SIOSendByte(UInt8 SIOdata)
- {
- short i;
-
- for (i=0;i<8;i++)
- {
- gvalue &= 0xF4;
- gvalue |= ((SIOdata >> i) & 0x01);
- SIORegWrite( gvalue);
- gvalue |= 0x02;
- SIORegWrite( gvalue);
- }
- }
-
- //=====================================================================================================
- //
- // SIOSendByte
- //
- //=====================================================================================================
- static void SIORegWrite(UInt8 data)
- {
- gZVRegisters->zvSIO = data;
- DelayForHardware(DurationToAbsolute(durationMicrosecond * 25)); // wait 15 µs
- }
-
-
- //=====================================================================================================
- //
- // SIOStart
- //
- //=====================================================================================================
- static void SIOStart(Boolean start)
- {
- if (start)
- {
- gvalue = gZVRegisters->zvSIO;
- gvalue &= 0xF7;
- gvalue |= 0x02;
- gZVRegisters->zvSIO = gvalue; // set CSK to 0
- DelayForHardware(DurationToAbsolute(durationMicrosecond * 20)); // wait 15 µs
- }
- else
- {
- gvalue |= 0x08; // set CS to 1
- SIORegWrite( gvalue);
- }
- }
-
- //=====================================================================================================
- //
- // AdjustSIOData
- //
- //=====================================================================================================
- static UInt8 AdjustSIOData(UInt8 data)
- {
- data -= 3;
- if (data > 6)
- return (data - 7);
- else if (data == 6)
- return (0x00 );
- else
- return (0x85 - data );
- }
-
- //=====================================================================================================
- //
- // CheckVsyn
- //
- //=====================================================================================================
- static UInt16 CheckVsyn(void)
- {
- UInt8 value,sync;
-
- // Vsync off check
- do
- {
- value = gZVRegisters->zvInterrupt ;
- } while (!(value & 0x02));
-
- // Vsync on check
- do
- {
- value = gZVRegisters->zvInterrupt ;
- } while ((value & 0x02) );
-
- sync = 1;
- return sync;
- }
-
-
-
-
-
-